package com.apes.scm.masterdata.party.service;

import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.mq.MQUtil;
import com.apes.framework.plugin.mq.annotation.Consumer;
import com.apes.framework.rop.converter.DateUtils;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.EventUtil;
import com.apes.scm.masterdata.party.model.Corporate;
import com.apes.scm.masterdata.party.model.Party;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.CorporateRepository;
import com.apes.scm.masterdata.party.repository.PartyIdentificationRepository;
import com.apes.scm.masterdata.party.repository.PartyRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apestech.framework.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;


/**
 * 功能：单位客户信息
 *
 * @author xul
 * @create 2018-01-23 14:35
 */
@Service("corporateCustomService")
public class CorporateCustomService extends DomainService {
    private static final String ROLE_TYPE = "Customer";

    @Autowired
    public PartyService partyService;

    @Autowired
    public PartyRoleService partyRoleService;

    @Autowired
    CorporateSerive corporateSerive;

    @Autowired
    CorporateRepository corporateRepository;

    @Autowired
    public PartyIdentificationRepository partyIdentificationRepository;

    @Autowired
    PartyRepository partyRepository;

    @Value("${apes.switched:false}")
    private Boolean switched;


    public Party save(SimpleRequest request) {
        Party party = request.getO(Party.class);
        party.setPartyType("corporate");     // 设置为法人单位

        List<Party> parties = partyRepository.findAll(JpaDsl.toCriteriaByEq("name", party.getName()));
        parties.forEach( p -> {
            if (p.getPartyRoleByType("Customer") != null) {
                throw new RuntimeException("已经存在相同名称的客户，请检查数据！");
            }
        });

        // 创建角色类型为  Customer
        party.addPartyRole(ROLE_TYPE,party.getCustomerCode());

        // 设置注册省份、注册城市、办公省份、办公城市
        corporateSerive.setCorporateCityAndProvince(party);

        Party result = partyService.saveAndFlush(party, ROLE_TYPE,party.getCustomerCode());

//        原：取不到客户编码 从PartyRoles里面可以取到
//        result.setCustomerCode(party.getCustomerCode());
        result.setCustomerCode(party.getPartyRoles().stream().filter(partyRole -> partyRole.getRole().getId().equals("Customer")).findFirst().get().getId());
        result.setOrigin(party.getPartyRoles().stream().filter(partyRole -> partyRole.getRole().getId().equals("Customer")).findFirst().get().getId());

        //产生同步至旧系统的body值
        JSONObject body = new JSONObject();
        synCustomer(result,body);

        result = partyService.saveAndFlush(party, ROLE_TYPE, party.getCustomerCode());
        result.setCustomerCode(party.getPartyRoles().stream().filter(partyRole -> partyRole.getRole().getId().equals("Customer")).findFirst().get().getId());

        /**
         * 本地调用测试
         * String topic = "event:cm.customer.synUnifiedExport";
         * EventUtil.sendSynEvent(this, topic, body).stream().findFirst().get();
         */

        //使用MQ发送异步推送旧系统同步创建
        if(!switched){
            MQUtil.publish("mq.customer.unified.export","单位客户创建", body);
        }

        return result;
    }


    // 更新客户信息
    public Party update(SimpleRequest request) {
        // 获取模型
        Party party = request.getO(Party.class);

        party.setUpdateDate(new Date());

        // 重新更新注册省份、注册城市、办公省份、办公城市（由于目前前端只保存了注册区县，办公区县）
        corporateSerive.setCorporateCityAndProvince(party);

        // 更新相关信息
        Party result = partyService.saveAndFlush(party, ROLE_TYPE, party.getCustomerCode());

//        原：取不到客户编码 从PartyRoles里面可以取到
//        result.setCustomerCode(party.getCustomerCode());
        PartyRole customer = party.getPartyRoles().stream().filter(partyRole -> partyRole.getRole().getId().equals("Customer")).findFirst().get();
        result.setCustomerCode(customer.getId());


        //产生同步至旧系统的body值
        JSONObject body = new JSONObject();
        synCustomer(party,body);
        customer.setLastUpdatedStamp(new Date());
        PartyRole partyRole = SpringManager.getBean(PartyRoleRepository.class).saveAndFlush(customer);
        /**
         * 本地调用测试
         * String topic = "event:cm.customer.synUnifiedExport";
         * EventUtil.sendSynEvent(this, topic, body).stream().findFirst().get();
         */

        //使用MQ发送异步推送旧系统同步创建
        if(!switched){
            MQUtil.publish("mq.customer.unified.export","单位客户更新", body);
        }

        return result;
    }

    /**
     * 定义界面弹窗
     * @param request
     */
    public Page<Party> findAll(SimpleRequest request) {
        Page<Party> partyPage = partyService.findPartyAllByTypeAndRole(request,"corporate","Customer");
        return partyPage;
    }



    public String addCustomerRole(SimpleRequest request) {
        return partyRoleService.addPartyTypeAndRoleId(request,"corporate","Customer");
    }


    public PartyRole findOne(String id) {
        return partyRoleService.findOne(id, "Customer");
    }

    /**
     * 根据SUCC查找客户公司信息
     * @param request uscc 唯一标识码
     * @return
     */
    public Party findBySUCC(SimpleRequest request) {
        String uscc = request.get("uscc");
        return partyService.findPartyByIdTypeAndIdValueAndRoleId("PIT_USCC",uscc, "Customer");
    }

    /**
     * 根据Code查找客户信息
     * @param request  code 客户编码
     * @return
     */
    public Party findByCode(SimpleRequest request) {
        return  partyService.findPartyByIdTypeAndIdValue("CustomerCode",request.get("code"));
    }

    /**
     * 根据Partner查找客户信息
     * @param request  Partner
     * @return
     */
    public Corporate findByPartner(SimpleRequest request) {
        if(StringUtil.isEmpty(request.get("partner").toString())) return  null;
        return  corporateRepository.findByPartyRole(request.get("partner").toString());
    }

    /**
     * 根据编码或者名称查询单位客户信息
     * @param request
     * @return
     */
    public Page<PartyRole> findCustomerByIdOrName(SimpleRequest request) {
        return partyRoleService.findCustomerByIdOrName(request);
    }

    public void synCustomer(Party party,JSONObject body){
        JSONObject synCustomer = new JSONObject();

        /** 老系统 基本信息 */
        synCustomer.put("KHID", party.getCustomerCode());
        synCustomer.put("KHMC", party.getName());
        synCustomer.put("KHJC", party.getAbbreviation());
        synCustomer.put("YXBJ", party.getCorporate().isValid() ? 1 : 0);
        synCustomer.put("BFJHBJ", party.getCorporate().isPortionDelivery() ? 1 : 0);
        synCustomer.put("DWBJ", party.getCorporate().isUnitTag() ? 1 : 0);
        synCustomer.put("DFDWBJ", party.getCorporate().isPayingUnitTag() ? 1 : 0);
        synCustomer.put("JTNBJ", party.getCorporate().isBlocInnerTag() ? 1 : 0);

        //TODO 客户组ID和客户列表ID
//        synCustomer.put("KHZID",party.getCorporate().getCustomerGroup().getId());
//        synCustomer.put("KHLBID",party.getCorporate().getCustomerCategory().getCode());

        String description = party.getCorporate().getCompanyNature().getDescription();
        if (description.equals("有限责任公司")) {
            synCustomer.put("GSXZID", 1);
        }
        if (description.equals("股份有限公司")) {
            synCustomer.put("GSXZID", 2);
        }
        if (description.equals("合伙企业")) {
            synCustomer.put("GSXZID", 8);
        }
        if (description.equals("国有企业")) {
            synCustomer.put("GSXZID", 4);
        }
        if (description.equals("个体户")) {
            synCustomer.put("GSXZID", 9);
        }
        synCustomer.put("GSXZMC", party.getCorporate().getCompanyNature().getDescription());
        synCustomer.put("DYGSID", party.getCorporate().getBelongCompany() == null ? "" : party.getCorporate().getBelongCompany().getId());
        synCustomer.put("DYGSMC", party.getCorporate().getBelongCompany() == null ? "" : party.getCorporate().getBelongCompany().getName());
        synCustomer.put("DYGYSID", party.getCorporate().getBelongSupplier() == null ? "" : party.getCorporate().getBelongSupplier().getId());
        synCustomer.put("DYGYSMC", party.getCorporate().getBelongSupplier() == null ? "" : party.getCorporate().getBelongSupplier().getName());
        synCustomer.put("BMID", party.getCorporate().getResponsibleBranch() == null ? "" : party.getCorporate().getResponsibleBranch().getId());
        synCustomer.put("BMMC", party.getCorporate().getResponsibleBranch() == null ? "" : party.getCorporate().getResponsibleBranch().getName());
        synCustomer.put("ZYTJ",party.getCorporate().getShipmentConditions() == null ? "" : party.getCorporate().getShipmentConditions().getDescription());
        synCustomer.put("JHDD",party.getCorporate().getDeliveryPlace());
        synCustomer.put("TS01", DateUtils.format(party.getLastUpdatedStamp(), "yyyyMMdd.HHmmss.SSS"));
        synCustomer.put("LRR", "admin");
        synCustomer.put("LRRQ_SJ", DateUtil.format(party.getCreateDate(), "yyyy-MM-dd HH:mm:ss"));

//        String topic = "event:cm.companyEntry.synCustomer";
//        Boolean flg = (Boolean) EventUtil.sendSynEvent(this, topic, synCustomer).stream().findFirst().get();
//        if (!flg) {
//            throw new RuntimeException("单位客户同步到旧框架时报错!");
//        }
        body.put("Customer", synCustomer);

        /** 客户 财务信息 */
        JSONObject synKHCWXX = new JSONObject();
        synKHCWXX.put("KHID", party.getCustomerCode());
        synKHCWXX.put("KHMC", party.getName());

        //TODO 客户信用组ID待优化
        synKHCWXX.put("KHXYZID", "001");

        synKHCWXX.put("KPBJ", party.getCorporate().isWantInvoice() ? 1 : 0);
        synKHCWXX.put("FPTT", party.getInvoiceTitle());
        synKHCWXX.put("FPDZ", party.getInvoiceAddress());
        synKHCWXX.put("FPDH", party.getInvoicePhone());
        // 税收类别编码
        String name = party.getCorporate().getTax().getName();
        if (name.equals("9%增值税")) {
            synKHCWXX.put("SSLBID", "J11");
        }
        if (name.equals("16%增值税")) {
            synKHCWXX.put("SSLBID", "J9");
        }
        if (name.equals("10%增值税")) {
            synKHCWXX.put("SSLBID", "J8");
        }
        if (name.equals("13%增值税")) {
            synKHCWXX.put("SSLBID", "J5");
        }
        if (name.equals("6%增值税")) {
            synKHCWXX.put("SSLBID", "J4");
        }
        if (name.equals("5%增值税")) {
            synKHCWXX.put("SSLBID", "J3");
        }
        if (name.equals("3%增值税")) {
            synKHCWXX.put("SSLBID", "J2");
        }
        if (name.equals("1.5%增值税")) {
            synKHCWXX.put("SSLBID", "J1");
        }
        if (name.equals("无税")) {
            synKHCWXX.put("SSLBID", "J0");
        }

//        String KHCWXXTopic = "event:cm.companyEntry.synKHCWXX";
//        Boolean KHCWXXFlg = (Boolean) EventUtil.sendSynEvent(this, KHCWXXTopic, synKHCWXX).stream().findFirst().get();
//        if (!KHCWXXFlg) {
//            throw new RuntimeException("客户财务信息同步到旧框架时报错!");
//        }

        body.put("KHCWXX", synKHCWXX);

        JSONObject synKHZCXX = new JSONObject();
        synKHZCXX.put("KHID", party.getCustomerCode());
        synKHZCXX.put("KHMC", party.getName());
        synKHZCXX.put("GJID", party.getCorporate().getRegCountry().getId());
        synKHZCXX.put("SFID", party.getCorporate().getRegProvince().getId().substring(0, party.getCorporate().getRegProvince().getId().length() - 4));
        synKHZCXX.put("CSID", party.getCorporate().getRegCity().getId().substring(0, party.getCorporate().getRegCity().getId().length() - 2));
        synKHZCXX.put("QXID", party.getCorporate().getRegCounty().getId());
        synKHZCXX.put("DZ", party.getCorporate().getRegAddress() == null ? "无" : party.getCorporate().getRegAddress());
        synKHZCXX.put("KHYH", party.getBank()  == null ? "无" : party.getBank());
        synKHZCXX.put("ZH", party.getBankAccount() == null ? "无" : party.getBankAccount());
        synKHZCXX.put("SH", party.getCorporate().getUscc());
        synKHZCXX.put("ZZJGDM", party.getCorporate().getUscc());
        synKHZCXX.put("FRDB", party.getCorporate().getLegalPerson());
        synKHZCXX.put("YZBM", party.getCorporate().getPostalCode());
        synKHZCXX.put("SJHM", "无");
        synKHZCXX.put("LXDH", "无");

//        String KHZCXXTopic = "event:cm.companyEntry.synKHZCXX";
//        Boolean KHZCXXFlg = (Boolean) EventUtil.sendSynEvent(this, KHZCXXTopic, synKHZCXX).stream().findFirst().get();
//        if (!KHZCXXFlg) {
//            throw new RuntimeException("客户注册信息同步到旧框架时报错!");
//        }
        body.put("KHZCXX", synKHZCXX);
    }

    /**
     * 推送异步消息至老系统
     *
     * @param request
     */
    @Consumer(topic = "mq.customer.unified.export")
    private void mqUnifiedExport(SimpleRequest request) {
        String topic = "event:cm.customer.synUnifiedExport";
        EventUtil.sendSynEvent(this, topic, request.getJO()).stream().findFirst().get();
    }
}
